home *** CD-ROM | disk | FTP | other *** search
/ MacTech 1 to 12 / MacTech-vol-1-12.toast / Source / MacTech® Magazine / Volume 07 - 1991 / 07.10 Oct 91 / Window Menubar Source ƒ / myAppleEvents.p < prev    next >
Encoding:
Text File  |  1991-07-25  |  12.7 KB  |  485 lines  |  [TEXT/PJMM]

  1. { ******************************************************** }
  2. { "myAppleEvents.p"                                        }
  3. {                                                          }
  4. { by John A. Love, III [ Washington Apple Pi Users' Group] }
  5. {                                                          }
  6. { using Symantec's "THINK Lightspeed Pascal", v 3.02       }
  7. { < based on Eric Soldan's "CShell" >                      }
  8. {                                                          }
  9. { ******************************************************** }
  10.  
  11.  
  12. UNIT myAppleEvents;
  13.  
  14. INTERFACE
  15.  
  16.     USES
  17.         Types, Memory, OSUtils, Quickdraw, Events, Files, AppleTalk, PPCToolbox, Processes, EPPC, Notification, AppleEvents, AERegistry, Script, Packages, Dialogs, CTBUtilities, Connections, GestaltEqu, wBMInterface, wBMGlobals, wBMMiscSubs, wBMWindSubs;
  18.  
  19.  
  20.     FUNCTION AppleEventsActive: BOOLEAN;
  21.     FUNCTION PPCToolboxActive: BOOLEAN;
  22.     FUNCTION AcceptHLEvent: OSErr;
  23.     FUNCTION MissedAnyParameters (event: EventRecord; theAEEvent: AppleEvent): OSErr;
  24.     FUNCTION InitPPCToolbox: OSErr;
  25.     FUNCTION DoAEOpenApplication (message: AppleEvent; reply: AppleEvent; refcon: LONGINT): OSErr;
  26.     FUNCTION DoAEOpenDocuments (message: AppleEvent; reply: AppleEvent; refcon: LONGINT): OSerr;
  27.     FUNCTION DoAEPrintDocuments (message: AppleEvent; reply: AppleEvent; refcon: LONGINT): OSErr;
  28.     FUNCTION DoAEQuitApplication (message: AppleEvent; reply: AppleEvent; refcon: LONGINT): OSErr;
  29.     FUNCTION DoAEMoveWindow (message: AppleEvent; reply: AppleEvent; refcon: LONGINT): OSErr;
  30.     FUNCTION InitAppleEvents: OSErr;
  31.     PROCEDURE CreateAndSendAE (class: AEEventClass; id: AEEventID);
  32.     PROCEDURE DoHighLevelEvent (event: EventRecord);
  33.  
  34.     TYPE
  35.         triplets = RECORD
  36.                 theEventClass: AEEventClass;
  37.                 theEventID: AEEventID;
  38.                 theHandler: ProcPtr;
  39.             END;
  40.  
  41.     CONST
  42.         _Gestalt = $A1AD;
  43.         noAppleEventsErr = -10000;
  44.         noPPCToolboxErr = -15000;
  45.         AEAlertID = 777;
  46.         kCustomEventClass = 'CUST';
  47.         kMoveWindClass = kCustomEventClass;
  48.         kMoveWindID = aeMove;
  49.  
  50.     VAR
  51.         myFeature: LONGINT;
  52.         gHasAppleEvents, gHasPPCToolbox: BOOLEAN;
  53.         keywordsToInstall: ARRAY[0..4] OF triplets;
  54.         err: OSErr;
  55.         returnString: Str255;
  56.         itemNbr: INTEGER;
  57.         theClient: TargetID;
  58.         clientRefcon: LONGINT;
  59.         currScreenDev, nextScreenDev: GDHandle;
  60.  
  61.  
  62.  
  63.  
  64. IMPLEMENTATION
  65.  
  66.  
  67.  
  68.  
  69.     FUNCTION AppleEventsActive: BOOLEAN;
  70. { Do we have a machine on which the Apple Events Manager exists ??? }
  71.  
  72.     BEGIN
  73.  
  74.         AppleEventsActive := FALSE;
  75.  
  76.         IF TrapAvailable(_Gestalt) THEN
  77.             IF Gestalt(gestaltAppleEventsAttr, myFeature) = noErr THEN
  78.                 IF BitTst(@myFeature, 31 - gestaltAppleEventsPresent) THEN
  79.                     AppleEventsActive := TRUE;
  80.  
  81.     END;   { AppleEventsActive }
  82.  
  83.  
  84.  
  85.     FUNCTION PPCToolboxActive: BOOLEAN;
  86. { Do we have a machine on which the PPCToolbox exists ??? }
  87.  
  88.     BEGIN
  89.  
  90.         PPCToolboxActive := FALSE;
  91.  
  92.         IF TrapAvailable(_Gestalt) THEN
  93.             IF Gestalt(gestaltPPCToolboxAttr, myFeature) = noErr THEN
  94.                 IF BitTst(@myFeature, 31 - gestaltPPCToolboxPresent) THEN
  95.                     PPCToolboxActive := TRUE;
  96.  
  97.     END;   { PPCToolboxActive }
  98.  
  99.  
  100.  
  101.     FUNCTION AcceptHLEvent: OSErr;
  102.  
  103.         VAR
  104.             myBuff: Ptr;
  105.             myLen: LONGINT;
  106.  
  107.     BEGIN
  108.  
  109.         myLen := 0;          { Start with zero to allow _AcceptHighLevelEvent }
  110.         myBuff := NIL;       {  to determine the size.                        }
  111.  
  112.         err := AcceptHighLevelEvent(theClient, clientRefcon, myBuff, myLen);
  113.         ;
  114.         IF err = bufferIsSmall THEN
  115.         BEGIN
  116.             myBuff := NewClearPtr(myLen);
  117.             err := AcceptHighLevelEvent(theClient, clientRefcon, myBuff, myLen);
  118.         END;
  119.  
  120.         AcceptHLEvent := err;
  121.  
  122.     END;   { AcceptHLEvent }
  123.  
  124.  
  125.  
  126.     FUNCTION MissedAnyParameters (event: EventRecord; theAEEvent: AppleEvent): OSErr;
  127.  
  128.         VAR
  129.             ignoredActualType: DescType;
  130.             missedKeyword: AEKeyword;
  131.             ignoredActualSize: Size;
  132.  
  133.     BEGIN
  134.  
  135.         err := AEGetAttributePtr(theAEEvent, keyMissedKeywordAttr, typeKeyword, ignoredActualType, @missedKeyword, SizeOf(missedKeyword), ignoredActualSize);
  136.  
  137.         IF err = noErr THEN   { We found some unused parameters. }
  138.         BEGIN
  139.             event.message := LONGINT(ignoredActualType);
  140.             event.where := Point(LONGINT(missedKeyword));
  141.             err := errAEEventNotHandled;
  142.         END   { noErr }
  143.         ELSE IF err = errAEDescNotFound THEN   { No more. }
  144.             err := noErr;
  145.  
  146.         MissedAnyParameters := err;
  147.  
  148.     END;   { MissedAnyParameters }
  149.  
  150.  
  151.  
  152.     FUNCTION InitPPCToolbox: OSErr;
  153.  
  154.     BEGIN
  155.  
  156.         gHasPPCToolbox := PPCToolboxActive;
  157.  
  158.         IF gHasPPCToolbox THEN
  159.         BEGIN
  160.  
  161.             IF BAND(myFeature, gestaltPPCSupportsRealTime) = 0 THEN
  162.             BEGIN
  163.                 err := PPCInit;
  164.                 IF err = noErr THEN
  165.                     err := Gestalt(gestaltPPCToolboxAttr, myFeature);
  166.             END
  167.             ELSE               { does NOT need initialization }
  168.                 err := noErr;
  169.  
  170.         END
  171.         ELSE
  172.             err := noPPCToolboxErr;
  173.  
  174.         InitPPCToolbox := err;
  175.  
  176.     END;   { InitPPCToolbox }
  177.  
  178.  
  179.  
  180.     PROCEDURE DisplayClientTypeAndCreator (theAEEvent: AppleEvent);
  181.  
  182.         VAR
  183.             nameStr: Str32;
  184.             senderType, senderCreator: INTEGER;
  185.             typeStr, creatorStr: Str255;
  186.             returnedType: DescType;
  187.             sourceOfAE: TargetID;
  188.             actualSize: Size;
  189.  
  190.     BEGIN
  191.  
  192.         IF gInitPPCToolbox = noErr THEN
  193.         BEGIN
  194.  
  195.             err := AEGetAttributePtr(theAEEvent, keyAddressAttr, typeTargetID, returnedType, @sourceOfAE, SizeOf(sourceOfAE), actualSize);
  196.             IF err = noErr THEN
  197.             BEGIN
  198.                 WITH sourceOfAE.name DO
  199.                 BEGIN
  200.  
  201.                     nameStr := name;
  202.                     IF portKindSelector = ppcByCreatorAndType THEN
  203.                     BEGIN
  204.                         NumToString(LONGINT(portType), typeStr);
  205.                         NumToString(LONGINT(portCreator), creatorStr);
  206.                     END
  207.                     ELSE   { ppcByString }
  208.                     BEGIN
  209.                         typeStr := copy(portTypeStr, 1, 4);   { Skip the length byte. }
  210.                         creatorStr := copy(portTypeStr, 5, 4);
  211.                     END;
  212.  
  213.                 END;   { WITH }
  214.  
  215.                 ParamText(concat('Client name: ‘', concat(nameStr, '’')), concat('Client type: ‘', concat(typeStr, '’')), concat('Client creator: ‘', concat(creatorStr, '’')), '');
  216.                 itemNbr := NoteAlert(AEAlertID, NIL);
  217.             END;   { noErr }
  218.  
  219.         END;   { gInitPPCToolbox }
  220.  
  221.     END;   { DisplayClientTypeAndCreator }
  222.  
  223.  
  224.  
  225.     FUNCTION DoAEOpenApplication (message: AppleEvent; reply: AppleEvent; refcon: LONGINT): OSErr;
  226.  
  227.     BEGIN
  228.  
  229.         ParamText('wBarDemo OBVIOUSLY!!', 'supports AppleEvent =', 'Open Application', '');
  230.         itemNbr := NoteAlert(AEAlertID, NIL);
  231.         DoAEOpenApplication := MissedAnyParameters(Event, message);
  232.         ;
  233.   { Done automatically by Apple Event Manager: }
  234.   { DoAEOpenApplication := AEPutParamPtr(reply, keyErrorNumber, typeShortInteger, @err, SizeOf(err)); }
  235.  
  236.         DisplayClientTypeAndCreator(message);
  237.  
  238.     END;   { DoAEOpenApplication }
  239.  
  240.  
  241.  
  242.     FUNCTION DoAEOpenDocuments (message: AppleEvent; reply: AppleEvent; refcon: LONGINT): OSerr;
  243.  
  244.     BEGIN
  245.  
  246.         ParamText('wBarDemo does NOT support', 'AppleEvent =', 'Open Documents', '');
  247.         itemNbr := StopAlert(AEAlertID, NIL);
  248.         DoAEOpenDocuments := errAEEventNotHandled;
  249.         ;
  250.   { DoAEOpenDocuments := AEPutParamPtr(reply, keyErrorNumber, typeShortInteger, @err, SizeOf(err)); }
  251.  
  252.         returnString := 'wBarDemo does NOT support AppleEvent = Open Documents';
  253.         err := AEPutParamPtr(reply, keyErrorString, typeChar, @returnString[1], length(returnString));
  254.  
  255.     END;   { DoAEOpenDocuments }
  256.  
  257.  
  258.  
  259.     FUNCTION DoAEPrintDocuments (message: AppleEvent; reply: AppleEvent; refcon: LONGINT): OSErr;
  260.  
  261.     BEGIN
  262.  
  263.         ParamText('wBarDemo does NOT support', 'AppleEvent =', 'Print Documents', '');
  264.         itemNbr := StopAlert(AEAlertID, NIL);
  265.         DoAEPrintDocuments := errAEEventNotHandled;
  266.         ;
  267.   { DoAEPrintDocuments := AEPutParamPtr(reply, keyErrorNumber, typeShortInteger, @err, SizeOf(err)); }
  268.  
  269.         returnString := 'wBarDemo does NOT support AppleEvent = Print Documents';
  270.         err := AEPutParamPtr(reply, keyErrorString, typeChar, @returnString[1], length(returnString));
  271.  
  272.     END;   { DoAEPrintDocuments }
  273.  
  274.  
  275.  
  276.     FUNCTION DoAEQuitApplication (message: AppleEvent; reply: AppleEvent; refcon: LONGINT): OSErr;
  277.  
  278.     BEGIN
  279.  
  280.         Done := TRUE;
  281.         ParamText('and NO doubt whatSOever!!', 'about AppleEvent =', 'Quit Application', '');
  282.         itemNbr := NoteAlert(AEAlertID, NIL);
  283.         DoAEQuitApplication := MissedAnyParameters(Event, message);
  284.         ;
  285.   { DoAEQuitApplication := AEPutParamPtr(reply, keyErrorNumber, typeShortInteger, @err, SizeOf(err)); }
  286.  
  287.         DisplayClientTypeAndCreator(message);
  288.  
  289.     END;   { DoAEQuitApplication }
  290.  
  291.  
  292.  
  293.     FUNCTION DoAEMoveWindow (message: AppleEvent; reply: AppleEvent; refcon: LONGINT): OSErr;
  294.  
  295.         VAR
  296.             returnedType: DescType;
  297.             movePoint: Point;
  298.             actualSize: Size;
  299.  
  300.  
  301.     BEGIN
  302.  
  303.         err := AEGetParamPtr(message, keyDirectObject, typeQDPoint, returnedType, @movePoint, SizeOf(movePoint), actualSize);
  304.         IF err = noErr THEN
  305.         BEGIN
  306.             MoveWindow(FrontWindow, movePoint.h, movePoint.v, true);
  307.             err := MissedAnyParameters(Event, message);
  308.         END;
  309.         ;
  310.         DoAEMoveWindow := err;
  311.  
  312.     END;   { DoAEMoveWindow }
  313.  
  314.  
  315.  
  316.     FUNCTION InitAppleEvents: OSErr;
  317.  
  318.         VAR
  319.             i: INTEGER;
  320.  
  321.     BEGIN
  322.  
  323.         gHasAppleEvents := AppleEventsActive;
  324.  
  325.         IF gHasAppleEvents THEN
  326.         BEGIN
  327.             WITH keywordsToInstall[0] DO
  328.             BEGIN
  329.                 theEventClass := kCoreEventClass;
  330.                 theEventID := kAEOpenApplication;
  331.                 theHandler := EventHandlerProcPtr(@DoAEOpenApplication);
  332.             END;
  333.             ;
  334.             WITH keywordsToInstall[1] DO
  335.             BEGIN
  336.                 theEventClass := kCoreEventClass;
  337.                 theEventID := kAEOpenDocuments;
  338.                 theHandler := EventHandlerProcPtr(@DoAEOpenDocuments);
  339.             END;
  340.             ;
  341.             WITH keywordsToInstall[2] DO
  342.             BEGIN
  343.                 theEventClass := kCoreEventClass;
  344.                 theEventID := kAEPrintDocuments;
  345.                 theHandler := EventHandlerProcPtr(@DoAEPrintDocuments);
  346.             END;
  347.             ;
  348.             WITH keywordsToInstall[3] DO
  349.             BEGIN
  350.                 theEventClass := kCoreEventClass;
  351.                 theEventID := kAEQuitApplication;
  352.                 theHandler := EventHandlerProcPtr(@DoAEQuitApplication);
  353.             END;
  354.             ;
  355.             WITH keywordsToInstall[4] DO
  356.             BEGIN
  357.                 theEventClass := kMoveWindClass;
  358.                 theEventID := kMoveWindID;
  359.                 theHandler := EventHandlerProcPtr(@DoAEMoveWindow);
  360.             END;
  361.  
  362.             i := 0;
  363.             REPEAT
  364.                 err := AEInstallEventHandler(keywordsToInstall[i].theEventClass, keywordsToInstall[i].theEventID, keywordsToInstall[i].theHandler, 0, false);
  365.                 i := i + 1;
  366.             UNTIL (i > 4) | (err <> noErr);
  367.  
  368.             InitAppleEvents := err;
  369.         END   { gHasAppleEvents }
  370.  
  371.         ELSE
  372.             InitAppleEvents := noAppleEventsErr;
  373.  
  374.     END;   { InitAppleEvents }
  375.  
  376.  
  377.  
  378.     PROCEDURE CreateAndSendAE (class: AEEventClass; id: AEEventID);
  379. { Given an event ID, this routine creates such an event and posts it with }
  380. { AESend.  Right now, all we know about are our own MoveWindow events.    }
  381.  
  382.         CONST
  383.             PRIORITY = kAENormalPriority;
  384.  
  385.         VAR
  386.  
  387.             err: OSErr;
  388.             me: ProcessSerialNumber;
  389.             theAevt: AppleEvent;
  390.             thisApp: AEAddressDesc;
  391.             theReply: AppleEvent;
  392.             thePoint: Point;
  393.             window: WindowPtr;
  394.             windRect, screen: Rect;
  395.             offsetForTitleBar, screenH, screenV, rand, offH, offV: INTEGER;
  396.  
  397.  
  398.     BEGIN
  399.  
  400.         window := FrontWindow;
  401.         IF window = NIL THEN
  402.             EXIT(CreateAndSendAE);
  403.  
  404.         windRect := window^.portRect;
  405.         LocalGlobal(windRect);
  406.         offsetForTitleBar := windRect.top - 1 - WindowPeek(window)^.strucRgn^^.rgnBBox.top;
  407.  
  408.         WITH me DO
  409.         BEGIN
  410.             highLongOfPSN := 0;
  411.             lowLongOfPSN := kCurrentProcess;
  412.         END;   { WITH }
  413.         ;
  414.         err := AECreateDesc(typeProcessSerialNumber, @me, SizeOf(me), thisApp);
  415.         IF err = noErr THEN
  416.             IF id = kMoveWindID THEN
  417.     { Create the Window moved event. This is just a random point passed to the }
  418.     { receiving application, which is expected to move the frontmost window.   }
  419.             BEGIN
  420.  
  421.                 IF aMac2 THEN
  422.                 BEGIN
  423.  
  424.                     WHILE nextScreenDev <> NIL DO
  425.                     BEGIN
  426.                         IF TestDeviceAttribute(nextScreenDev, screenDevice) & TestDeviceAttribute(nextScreenDev, screenActive) THEN
  427.                             Leave   { WHILE loop }
  428.                         ELSE
  429.                             nextScreenDev := GetNextDevice(nextScreenDev);
  430.                     END;   { WHILE }
  431.                     ;
  432.                     IF nextScreenDev <> NIL THEN
  433.                         currScreenDev := nextScreenDev
  434.                     ELSE
  435.                         currScreenDev := GetMainDevice;   { Restart at the beginning. }
  436.                     screen := currScreenDev^^.gdRect;
  437.                     nextScreenDev := GetNextDevice(currScreenDev);
  438.  
  439.                 END   { aMac2 }
  440.                 ELSE
  441.                     screen := screenBits.bounds;
  442.  
  443.                 WITH screen DO
  444.                 BEGIN
  445.         { InsetRect(screen, 10, 10); }
  446.                     screenH := right - left - 20;
  447.                     screenV := bottom - top - 20;
  448.                     rand := Random;
  449.                     offH := left + 10;
  450.                     offV := top + mBarHt + 10 + offsetForTitleBar;
  451.                     SetPt(thePoint, offH + abs(rand MOD screenH), offV + abs(rand MOD screenV));
  452.                 END;   { WITH }
  453.  
  454.                 err := AECreateAppleEvent(class, id, thisApp, kAutoGenerateReturnID, kAnyTransactionID, theAevt);
  455.  
  456.                 IF err = noErr THEN
  457.        { Things are still cool... }
  458.                     err := AEPutParamPtr(theAevt, keyDirectObject, typeQDPoint, @thePoint, SizeOf(Point));
  459.  
  460.                 IF err = noErr THEN
  461.                     err := AESend(theAevt, theReply, kAENoReply, PRIORITY, 0, NIL, NIL);
  462.  
  463.                 err := AEDisposeDesc(thisApp);
  464.  
  465.             END;   { kMoveWindID }
  466.  
  467.     END;   { CreateAndSendAE }
  468.  
  469.  
  470.  
  471.     PROCEDURE DoHighLevelEvent (event: EventRecord);
  472. { Simply calls AEProcessAppleEvent and reports any errors to the client.    }
  473. { AEProcessAppleEvent looks in its table of registered events and sees if   }
  474. { the current event is registered.  If so, it calls the routine associated  }
  475. { with that event.                                                          }
  476.  
  477.     BEGIN
  478.         IF gInitAppleEvents = noErr THEN
  479.             err := AEProcessAppleEvent(event);
  480.     END;   { DoHighLevelEvent }
  481.  
  482.  
  483.  
  484.  
  485. END.   { UNIT = myAppleEvents }